Exploration des Données des Bâtiments de Seattle


Ce notebook contient la phase d'exploration des variables du jeu de données des bâtiments de la ville de Seattle. Le but étant de modéliser la consommation d'énergie annuelle, un effort sera réalisé pour montrer la dépendance de cette variable cible avec les autres variables du jeu de données. Le jeu de données a été nettoyé au préalable afin de sélectionner les variables d'entrées pertinentes pour notre modélisation.

In [1]:
## traitement des données
import pandas as pd
import numpy as np

## visualisation avec Plotly
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
import ipywidgets as ipw

import myutility.myfunction as myfunc
In [2]:
## template plotly pour la visualisation
pio.templates.default='seaborn'

L'échantillon de données contient 3370 bâtiments, renseignés par 26 variables.

In [3]:
## données  2016
data = pd.read_csv('dataset/2016-building-energy-benchmarking-cleaned.csv')
data.shape
Out[3]:
(3370, 26)

On peut séparer les variables du jeu de données en trois catégories :

  1. variables catégorielles (object)
  2. variables numériques discrètes (int64)
  3. variables numériques continues (float64)
In [4]:
## ensembles des variables du dataset
data.dtypes.sort_values()
Out[4]:
DefaultData                           bool
OSEBuildingID                        int64
PropertyGFABuilding(s)               int64
PropertyGFAParking                   int64
PropertyGFATotal                     int64
YearBuilt                            int64
NumberofFloors                       int64
NumberofBuildings                  float64
ENERGYSTARScore                    float64
Latitude                           float64
TotalGHGEmissions                  float64
LargestPropertyUseTypeGFA          float64
SiteEnergyUseWN(kBtu)              float64
SecondLargestPropertyUseTypeGFA    float64
Longitude                          float64
ThirdLargestPropertyUseTypeGFA     float64
ComplianceStatus                    object
Outlier                             object
LargestPropertyUseType              object
SecondLargestPropertyUseType        object
NaturalGasAvailabe                  object
Neighborhood                        object
PrimaryPropertyType                 object
BuildingType                        object
ThirdLargestPropertyUseType         object
SteamAvailabe                       object
dtype: object

Le jeu de données contient des variables de type numérique (int64 & float64), et des variables de type catégorie (object).


La variable cible qui sera modélisée est la consommation d'énergie annuelle corrigée (SiteEnergyUseWN(kBtu)). On étudie dans cette étude exploratoire la relation des variables avec cette variable cible.

I. Variables Catégorielles

Le nombre de bâtiments renseignés pour chaque variable catégorielle est affiché ci-dessous. La plupart des variables catégorielles sont completement renseignées (n=3370).

In [5]:
listCategVar = data.dtypes == 'object'
listCategVar = listCategVar[listCategVar].index.tolist()
data[listCategVar].count()
Out[5]:
BuildingType                    3370
PrimaryPropertyType             3370
Neighborhood                    3370
LargestPropertyUseType          3355
SecondLargestPropertyUseType    1679
ThirdLargestPropertyUseType      596
ComplianceStatus                3370
Outlier                           32
NaturalGasAvailabe              3366
SteamAvailabe                   3366
dtype: int64

Pour chaque variable catégorielle, on regroupe les modalités les moins fréquentes ($<5\%$) dans le groupe 'Other'. Cette technique va nous permettre de facilité la visualisation de ce type de variable

In [6]:
myfunc.gathercateg(data, dropna=False)

Pour chaque variable catégorielle, on affiche

  • un diagramme circulaire, qui indique la représentation de chaque modalité;
  • une boîte à moustache, qui montre la dépendance de chaque modalité avec la variable cible.
In [7]:
piechart= {}
boxplot = {}

for categVar in listCategVar:

    piefig = go.FigureWidget(px.pie(data, names=categVar, title=categVar,
                     color_discrete_sequence=px.colors.sequential.haline_r))
    piefig.update_traces(sort=False,textinfo='percent+label',rotation=90, pull=0.03)
    piefig.update_layout(width=400,showlegend=False, margin_r=130, margin_l=130)
    
    boxfig = go.FigureWidget(px.box(data.sample(n=1000, random_state=2),
                    x=categVar, y='SiteEnergyUseWN(kBtu)', range_y=[-3e5,35e6]))
    boxfig.update_layout(margin_b=50, margin_l=150,width=550)
    boxfig.update_traces(marker_opacity=0)
 

    piechart[categVar] = piefig
    boxplot[categVar] = boxfig
In [8]:
ipw.HBox([piechart['NaturalGasAvailabe'], boxplot['NaturalGasAvailabe']])

Vue de Seattle, avec son importante diversité de batîments. Au premier plan : le quartier des affaires de la ville, Downtown Seatle (Wikipedia).

In [9]:
ipw.HBox([piechart['BuildingType'], boxplot['BuildingType']])
In [10]:
ipw.HBox([piechart['PrimaryPropertyType'], boxplot['PrimaryPropertyType']])

Carte de la ville de Seattle, divisée selon ses quartiers.

In [11]:
ipw.HBox([piechart['Neighborhood'], boxplot['Neighborhood']])
In [12]:
ipw.HBox([piechart['LargestPropertyUseType'], boxplot['LargestPropertyUseType']])
In [13]:
ipw.HBox([piechart['SecondLargestPropertyUseType'], boxplot['SecondLargestPropertyUseType']])
In [14]:
ipw.HBox([piechart['ThirdLargestPropertyUseType'], boxplot['ThirdLargestPropertyUseType']])
In [15]:
ipw.HBox([piechart['ComplianceStatus'], boxplot['ComplianceStatus']])
In [16]:
ipw.HBox([piechart['Outlier'], boxplot['Outlier']])


II. Variables Numériques Discrètes

Le nombre de bâtiments renseignés pour chaque variable numérique disrète est affiché ci-dessous. Toutes les variables numériques discrètes sont completement renseignées (n=3370).

In [17]:
listDiscreteVar = data.dtypes == 'int64'
listDiscreteVar = listDiscreteVar[listDiscreteVar].index.tolist()
data[listDiscreteVar].count()
Out[17]:
OSEBuildingID             3370
YearBuilt                 3370
NumberofFloors            3370
PropertyGFATotal          3370
PropertyGFAParking        3370
PropertyGFABuilding(s)    3370
dtype: int64
In [18]:
## Intervalle des x et binning des variables d'entrée
binsize = {}
binsize['YearBuilt']              = {'start' : 1900.0, 'end' : 2015.0,   'size' : 5}
binsize['PropertyGFATotal']       = {'start' : 0.0,    'end' : 300000.0, 'size' : 20000}
binsize['PropertyGFABuilding(s)'] = {'start' : 0.0,    'end' : 300000.0, 'size' : 20000}
binsize['PropertyGFAParking']     = {'start' : 0.0,    'end' : 30000.0,  'size' : 2000}
In [19]:
for elt in binsize:
    nameFlooredVar = elt + 'Floor' + str(binsize[elt]['size'])
    data[nameFlooredVar] = (data[elt] - data[elt] % 5)
In [20]:
figDhist = {}
figDbox = {}

for elt in binsize:
    ## histogram, variable d'entrée (x)
    figDhist[elt] = go.FigureWidget(px.histogram(data, x=elt))

    figDhist[elt].update_traces(xbins=binsize[elt], opacity=.85)
    figDhist[elt].update_layout(width=480, #margin_r=100,
        xaxis=dict(
        range=[binsize[elt]['start'] - binsize[elt]['size'] / 2, binsize[elt]['end']])
        )

    ## nouvelle colonne où on discretise les valeurs (pas = taille de bin)
    nameFlooredVar = elt + 'Floor' + str(binsize[elt]['size'])
    data[nameFlooredVar] = (data[elt] - data[elt] % binsize[elt]['size'])
    
    ## intervalle des x
    min_x = binsize[elt]['start'] - binsize[elt]['size'] / 2
    max_x = binsize[elt]['end'] + binsize[elt]['size'] / 2
    
    ## box plot, Mediane[variable cible] (y) versus Variable d'entrée (x)
    figDbox[elt] = go.FigureWidget(px.box(data, y='SiteEnergyUseWN(kBtu)', x=nameFlooredVar,
                                 range_y= [-30e4,25e6], range_x=[min_x, max_x]))
    figDbox[elt].update_traces(marker_opacity=0)
    figDbox[elt].update_layout(width=480, xaxis_title_text = elt
                              # , margin_l=50
                              )
    
    data.drop(nameFlooredVar, axis='columns') ## supprime la colonne floored

Année de construction

In [21]:
ipw.HBox([figDhist['YearBuilt'], figDbox['YearBuilt']])

Surface de plancher totale

In [22]:
ipw.HBox([figDhist['PropertyGFATotal'], figDbox['PropertyGFATotal']])

Surface au plancher du batîment

In [23]:
ipw.HBox([figDhist['PropertyGFABuilding(s)'], figDbox['PropertyGFABuilding(s)']])

Surface du parking

In [24]:
ipw.HBox([figDhist['PropertyGFAParking'], figDbox['PropertyGFAParking']])


II. Variables Numériques Continues

Le nombre de bâtiments renseignés pour chaque variable numérique continue est affiché ci-dessous. La plupart des variables numériques continues sont presque completement renseignées (n=3370).

In [25]:
listContinuousVar = data.dtypes == 'float64'
listContinuousVar = listContinuousVar[listContinuousVar].index.tolist()
data[listContinuousVar].count()
Out[25]:
Latitude                           3370
Longitude                          3370
NumberofBuildings                  3367
LargestPropertyUseTypeGFA          3355
SecondLargestPropertyUseTypeGFA    1679
ThirdLargestPropertyUseTypeGFA      596
ENERGYSTARScore                    2532
SiteEnergyUseWN(kBtu)              3369
TotalGHGEmissions                  3366
dtype: int64

Nombre d'étages

In [26]:
px.histogram(data, x='NumberofFloors')

Surface d'utilisation principale

In [27]:
px.histogram(data, x='LargestPropertyUseTypeGFA')

Surface d'utilisation secondaire

In [28]:
px.histogram(data, x='SecondLargestPropertyUseTypeGFA')